/**
 * @作者 伟子涵
 * @微信公号 搬砖暗夜码农
 * @开源项目 $ https://gitee.com/zhouwei5208888
 * @我的博客 $ http://itzhouwei.com
 * @创建时间 2023/10/17 10:16
 */
package com.itzhouwei.netty.day6;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * @description:
 * @author：zw，微信：yingshengzw
 * @date: 2023/10/17
 * @Copyright： 公众号：搬砖暗夜码农 | 博客：https://itzhouwei.com - 沉淀、分享、成长，让自己和他人都能有所收获！
 */
@Slf4j
public class ServerChannelHandler extends SimpleChannelInboundHandler<byte[]> {

    /***
     * 拿到传过来的msg数据，开始处理
     * @param channelHandlerContext
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, byte[] msg) throws Exception {
        String vv=JuDianUtil.bytesToHexString(msg);
        log.info("Netty tcp server receive--- message: {}",  vv);
        byte[] bb= JuDianUtil.hexStringToByteArray(vv);

        log.info("Netty tcp server receive message------: {}", Crc3Util.getCRC3(bb,null));

          //拿到指令
          String cmd = JuDianUtil.getMsgCmd(vv);
          String pileCode = JuDianUtil.getPileNum(vv);
//
//        log.info("Netty tcp: {}", cmd);
//        log.info("Netty tcp: {}", pileCode);



//        itBookService.save(new TBook("1231", (String) msg));
//        redisUtil.set("123",new TBook(1,"1231", (String) msg),60);

       channelHandlerContext.writeAndFlush(JuDianUtil.hexStringToBytes("680c000000020361002001101300c17f")).syncUninterruptibly();
    }





    /**
     * 活跃的、有效的通道
     * 第一次连接成功后进入的方法
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        log.info("tcp client "+getRemoteAddress(ctx)+" connect success");
        NettyTcpServer.map.put(getIPString(ctx),ctx.channel());



    }




    /**
     * 不活动的通道
     * 连接丢失后执行的方法（client端可据此实现断线重连）
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // 删除Channel Map中失效的Client
        log.info("tcp client "+getRemoteAddress(ctx)+" 删除Channel");
        NettyTcpServer.map.remove(getIPString(ctx));
        ctx.close();
    }

//    掉线移除
//    @Override
//    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
//
//        log.info("tcp client "+getRemoteAddress(ctx)+" handlerRemoved");
//        NettyTcpServer.map.remove(getIPString(ctx));
//        ctx.close();
//    }




    /**
     * 异常处理
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        // 发生异常 关闭连接
        log.error("引擎{}的通道发生异常，断开连接",getRemoteAddress(ctx));
        ctx.close();
    }

    /**
     * 心跳机制 超时处理
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        String socketString = ctx.channel().remoteAddress().toString();
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state()== IdleState.READER_IDLE) {
                log.info("Client: "+socketString+" READER_IDLE读超时");
                ctx.disconnect();
            }else if (event.state()==IdleState.WRITER_IDLE){
                log.info("Client: "+socketString+" WRITER_IDLE写超时");
                ctx.disconnect();
            }else if (event.state()==IdleState.ALL_IDLE){
                log.info("Client: "+socketString+" ALL_IDLE总超时");
                ctx.disconnect();
            }
        }
    }

    /**
     * 获取client对象：ip+port
     * @param channelHandlerContext
     * @return
     */
    public String getRemoteAddress(ChannelHandlerContext channelHandlerContext){
        String socketString = "";
        socketString = channelHandlerContext.channel().remoteAddress().toString();
        return socketString;
    }

    /**
     * 获取client的ip
     * @param channelHandlerContext
     * @return
     */
    public String getIPString(ChannelHandlerContext channelHandlerContext){
        String ipString = "";
        String socketString = channelHandlerContext.channel().remoteAddress().toString();
        int colonAt = socketString.indexOf(":");
        ipString = socketString.substring(1,colonAt);

        return ipString;
    }


}
